import isObject from "./isObject"
import store from '../src/store';
// 单利模式
class wss {
	// 断开重连的状态
	static duanKaiChongLianFlag = true;
	// 断开重连的次数
	static duanKaiCiShu = 10
	// 断开重连初试定时时间
	static duanKaiTime = 1000
	// webscoket 服务 链接存储值
	static ws = null
	// 心跳检测 
	static xinTiaoFlag = true
	// 离线消息队列
	static XiaoXiList = []
	
	static async connectWS() {
	
		// console.log(wss.duanKaiChongLianFlag,15)
		// console.log("jinlai le ",wss.duanKaiChongLianFlag)
		// 如果允许断开重连 
		if (wss.duanKaiChongLianFlag) {
			// 如果断开次数大于0 就一直循环
			while (wss.duanKaiCiShu > 0) {
				// 第一次链接 不需要定时  也就是说 一进入页面 就开始执行 
				wss.initWs()
				// 等待 duanKaiTime 秒后 在继续执行
				await wss.WAITS(wss.duanKaiTime)
				// 每次重连的时间 在原基础上 扩大2倍
				wss.duanKaiTime *= 2
				// 重连次数 每次减一
				wss.duanKaiCiShu--
			}
		}
	}

	static initWs() {
		wss.ws = new WebSocket("ws://127.0.0.1:3003")

		wss.ws.onopen = async () => {
			// 次数改成0 是为了终止循环 
			wss.duanKaiCiShu = 0
			// 断开重连状态改成 false
			wss.duanKaiChongLianFlag = false
			// 将消息队列里面的内容 发送一遍
			for(var $i=0;$i<wss.XiaoXiList.length;$i++){
				wss.sendMsg(wss.XiaoXiList[$i])
			}
			// 心跳检测定时器 每3秒执行一次
			let xinTiaoIVL = setInterval(() => {
				// 如果心跳的装填 是true 代表正常 就继续向服务端推送数据
				if (wss.xinTiaoFlag) {
					// 推送数据前  先将状态改为false  当服务端给了回复之后 在将此状态 改为true
					wss.xinTiaoFlag = false
					// 向服务端推送数据
					wss.sendMsg({ type: "heart" })
				} else {
					// 如果走到else 说明链接超时了  
					// 如果链接超时 需要 清空定时器
					clearInterval(xinTiaoIVL)
					// 清空定时器
					// xinTiaoIVL = null
					// 回复重连次数 
					wss.duanKaiCiShu = 10
					// 更改 重连装填 为允许重连
					wss.duanKaiChongLianFlag = true
					// 心跳状态回复为 正常
					wss.xinTiaoFlag = true
					// 调用重连方法 进行重连操作
					wss.connectWS()
				}
			}, 3000)
		}

		wss.ws.onmessage = (evt) => {
			// console.log("收到消息")
			// console.log(evt.data, 13)
			let data
			try {
				// JSON.parse("12345")
				data = JSON.parse(evt.data)
				
				if (isObject(data)) {
					// console.log(data)
					// 如果type是 心跳检测
					// store.dispatch('heart',data)
					store.dispatch(data.type,data)
					if (data.type === 'heart') {
						// console.log("链接正常")
						// 将心跳状态 回复成正常 【xinTiaoFlag =false 代表服务端没有回复消息 就是异常状态】
						wss.xinTiaoFlag = true
						
					}
					// 存vuex 

				} else {
					console.log(data, "这是个字符串")
				}

			} catch (e) {
				console.log(data)
				//TODO handle the exception
			}
		}
		wss.ws.onclose = () => {
			// connectWS()
		}
		wss.ws.onerror = (err) => {
			console.log("error")
		}

	}



	static WAITS(times=1000) {
		return new Promise((resolve) => {
			setTimeout(() => {
				resolve(true)
			}, times)
		});
	}
	
	/**
	 * data 必须是一个对象  
	 */
	static sendMsg = (data) => {
		// 说明  已经链接了 
		// console.log(wss.ws,124)
		if(wss.ws || wss.ws.readyState!=0){
			var flag
			try {
				// constructor 他检测 null 和 undefined 会报错
				// typeof 检测null  array function 都是 obejct
				// instanceof 判断数组时 也是ture [] instanceof Object ===true
				flag = (data).constructor === Object
			} catch (e) {
				flag = false
			}
			try{
				if (flag) {
					wss.ws.send(JSON.stringify(data))
				} else {
					wss.ws.send(JSON.stringify(data))
				}
			}catch(e){
				//TODO handle the exception
				console.log("还没链接呢",data,142)
				wss.XiaoXiList.push(data)
				// 对离线消息进行去重复 操作  
				wss.XiaoXiList = [...new Set(wss.XiaoXiList.map(JSON.stringify))].map(JSON.parse);
			}
			// console.log(flag, 32)
		}else{
			// 还没链接呢 
			console.log("还没链接呢")
		}
	}
}

export default wss


